package cDB

import (
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/mongo"

	"gitee.com/csingo/cCommon"
	"gitee.com/csingo/cLog"
)

func findMongoClient(ctx *gin.Context, name string) *mongo.Database {
	if client, _ := ctx.Get(cCommon.Context_MongoDBTransaction); client != nil {
		return client.(*mongo.Database)
	} else {
		client := Client[*mongo.Database](ctx, name)
		if client == nil {
			cLog.WithContext(ctx, map[string]any{
				"source":     "cDB.findMongoClient",
				"connection": name,
			}).Panic("database connection is not exists")
		}

		return client
	}
}

func WithContextCollection(ctx *gin.Context, model ModelInterface) *mongo.Collection {
	name := model.Connection(ctx)
	client := findMongoClient(ctx, name)
	result := client.Collection(model.TableName())
	return result
}

func StartMongoTransaction(ctx *gin.Context, name string, f func(sc mongo.SessionContext) error) error {
	db := Client[*mongo.Database](ctx, name)
	client := db.Client()

	session, err := client.StartSession()
	if err != nil {
		return err
	}
	defer session.EndSession(ctx)

	if err = mongo.WithSession(ctx, session, func(sc mongo.SessionContext) error {
		var e error
		if e = session.StartTransaction(); e != nil {
			return e
		}

		if e = f(sc); e != nil {
			_ = session.AbortTransaction(sc)
			return e
		}

		if e = session.CommitTransaction(sc); e != nil {
			return e
		}

		return nil
	}); err != nil {
		return err
	}

	return err
}
